package com.goldcn.sys.controller;

import com.goldcn.common.CommonUtils;
import com.goldcn.common.RSAUtils;
import com.goldcn.common.model.DataResult;
import com.goldcn.sys.dto.LoginDto;
import com.goldcn.sys.dto.RasKey;
import com.goldcn.sys.model.util.ValidateCode;
import com.goldcn.sys.service.RedisService;
import com.goldcn.sys.service.SysUserLoginService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.codec.binary.StringUtils;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.security.PrivateKey;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * Created by Administrator on 2016/9/3.
 */
@RestController
@RequestMapping(value = "sysUser")
@Api(value = "登录", description = "用户登录")
public class UserLoginController {
    @Autowired
    SysUserLoginService loginService;

    @Autowired
    RedisService redisService;

    /**
     * 登录，需要ras加密
     */
    @RequestMapping(value = "/userLogin", method = RequestMethod.POST)
    public DataResult<Object> login(@RequestBody LoginDto loginDto, HttpServletRequest request) throws Exception {
        //从redis获取私钥并解密
        PrivateKey key = (PrivateKey) redisService.loadKey(loginDto.getRasId());
        byte[] en_result = RSAUtils.hexStringToBytes(loginDto.getPassWord());
        byte[] de_result = RSAUtils.decrypt(key, en_result);
        StringBuffer sb = new StringBuffer();
        sb.append(StringUtils.newStringUtf8(de_result));
        loginDto.setPassWord(CommonUtils.MD5(sb.reverse().toString()));
        return loginService.doLogin(loginDto, request);
    }

    @ApiOperation(value = "验证码")
    @RequestMapping(value = "valiCode", method = RequestMethod.GET)
    public void getCode(HttpServletRequest reqeust,
                        HttpServletResponse response) throws ServletException, IOException {
        // 设置响应的类型格式为图片格式
        response.setContentType("image/jpeg");
        //禁止图像缓存。
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);

        HttpSession session = reqeust.getSession();
        System.out.println("getcode=" + session.getId());
        ValidateCode vCode = new ValidateCode(120, 40, 4, 100);
        session.setAttribute("code", vCode.getCode());
        vCode.write(response.getOutputStream());
    }


    /**
     * 获取公钥
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/rasKey", method = RequestMethod.GET)
    @ResponseBody
    public DataResult<RasKey> getRASKey() throws Exception {


        return loginService.getRASKey();
    }

    /**
     * 用户退出
     *
     * @param userID
     * @return
     */
    @RequestMapping(value = "/loginOut", method = RequestMethod.POST)
    public DataResult<String> loginOut(HttpServletRequest request, String userID, String platform) {
        return loginService.loginOut(request, userID, platform);
    }

    /**
     * 忘记密码，修改密码
     */
    @RequestMapping(value = "/passWord", method = RequestMethod.POST)
    public Object updatePassWord(@RequestBody LoginDto loginDto) throws Exception {
        PrivateKey key = (PrivateKey) redisService.loadKey(loginDto.getRasId());
        byte[] oldDn_result = RSAUtils.hexStringToBytes(loginDto.getOldPassWord());
        byte[] odlDe_result = RSAUtils.decrypt(key, oldDn_result);
        StringBuffer oldSb = new StringBuffer();
        oldSb.append(StringUtils.newStringUtf8(odlDe_result));
        loginDto.setOldPassWord(CommonUtils.MD5(oldSb.reverse().toString()));
        byte[] en_result = RSAUtils.hexStringToBytes(loginDto.getPassWord());
        byte[] de_result = RSAUtils.decrypt(key, en_result);
        StringBuffer sb = new StringBuffer();
        sb.append(StringUtils.newStringUtf8(de_result));
        loginDto.setPassWord(CommonUtils.MD5(sb.reverse().toString()));
        return loginService.updatePassWord(loginDto);
    }

    @Autowired
    protected Client client;
    /**
     * es index
     */
    private static final String ES_INDEX = "book";
    /**
     * es type
     */
    private static final String ES_TYPE = "book";

//    //创建客户端
//    private static void createClient() throws Exception {
//        if (client == null) {
//            synchronized (UserLoginController.class) {
//                Settings settings = Settings.settingsBuilder().put("cluster.name", "elasticsearch").put("client.transport.sniff", true).build();
//                client = TransportClient.builder().settings(settings).build()
//                        .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("120.78.216.132"), 9300));
//                System.out.println("启动客户端：" + client);//启动客户端：org.elasticsearch.client.transport.TransportClient@16e2a4c8
//            }
//        }
//    }


    //获取日期 年月日 时分秒
    public static String tranTime() {
        return new SimpleDateFormat("YYYY-MM-DD HH:mm:ss").format(new Date());
    }

    /**
     * 创建es库并导入数据
     */
    private  String createIndex(String message) {
        //json字符串    {"username":"zhengyong","postDate":"19-01-11 10:56:04","message":"create"}

        JSONObject json = new JSONObject();
        json.put("username",message);
        json.put("postDate",tranTime());
        json.put("message",message);

        IndexResponse response = client.prepareIndex(ES_INDEX, ES_TYPE).setSource(json.toString()).get();
        System.out.println(String.format("create index response: %s", response.toString()));
        return response.getId();
    }


    /**
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/index/{message}", method = RequestMethod.POST)
    @ResponseBody
    public DataResult<RasKey> addIndex(@PathVariable String message) throws Exception {

       // createClient();
        createIndex(message);


        return loginService.getRASKey();
    }


    /**
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/search/{message}", method = RequestMethod.POST)
    @ResponseBody
    public DataResult<RasKey> searchIndex(@PathVariable String message) throws Exception {
        //createClient();

        QueryBuilder queryBuilder = QueryBuilders.termQuery("username", message);//有查询条件 keyword

        //NativeSearchQueryBuilder  queryBuilder = new NativeSearchQueryBuilder();

        SearchResponse sResponse = client.prepareSearch(ES_INDEX).setTypes(ES_TYPE).setQuery(queryBuilder).setSize(1000).execute().actionGet();
        SearchHits hits = sResponse.getHits();
        List<String> list = new ArrayList<String>();
        SearchHit[] hitArray = hits.hits();
        Map<String, Object> map;
        for (SearchHit hit : hitArray) {
            map = hit.getSource();
            String username = (String) map.get("username");
            String postDate = (String) map.get("postDate");
            String msg = (String) map.get("message");
            StringBuilder br = new StringBuilder();
            br.append(username).append("_").append(msg).append("_").append(postDate);
            list.add(br.toString());
        }
        System.out.println(String.format("query data count=%s, list : %s", list.size(), JSONArray.fromObject(list).toString()));


        return loginService.getRASKey();
    }

}
